// Open Source: MIT License (http://www.opensource.org/licenses/mit-license.php)
// Project: YoProgramo.NET (http://code.google.com/p/yoprogramo/)
// Autor: Fabian Figueredo (info@fabianfigueredo.com.ar)
// Blog: blog.yoprogramo.net

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using YoProgramo.Domain.BusinessLogic.Attributes;
using YoProgramo.Domain.BusinessLogic.Extensions;
using YoProgramo.Domain.BusinessLogic.Service;
using YoProgramo.Domain.Core;
using YoProgramo.Domain.Core.Entities;
using YoProgramo.Domain.Core.Interfaces;
using YoProgramo.Infrastructure.Tools.Markdown;
using YoProgramo.Infrastructure.Tools.PagedList;

namespace YoProgramo.Web.Controllers
{
    [YpAuthorize(Roles = new Roles[] { Roles.Administrator })]
    public class AdminController : Controller
    {

        public AdminController(ICommentService commentService, 
            ICommentRepository commentRepository, 
            IStoryRepository storyRepository, 
            IUserRepository userRepository,
            IMarkAsSpamService<Comment> spamCommentService,
            IMarkAsSpamRepository<Comment> spamCommentRepository,
            IMarkAsSpamService<Story> spamStoryService,
            IMarkAsSpamRepository<Story> spamStoryRepository
            )
        {
            Commentservice = commentService;
            Commentrepository = commentRepository;
            Storyrepository = storyRepository;
            Userrepository = userRepository;
            SpamCommentService = spamCommentService;
            SpamStoryService = spamStoryService;
            SpamCommentRepository = spamCommentRepository;
            SpamStoryRepository = spamStoryRepository;
        }

        public ICommentService Commentservice { get; set; }
        public ICommentRepository Commentrepository { get; set; }
        public IStoryRepository Storyrepository { get; set; }
        public IUserRepository Userrepository { get; set; }

        public IMarkAsSpamService<Comment> SpamCommentService { get; set; }
        public IMarkAsSpamService<Story> SpamStoryService { get; set; }

        public IMarkAsSpamRepository<Comment> SpamCommentRepository { get; set; }
        public IMarkAsSpamRepository<Story> SpamStoryRepository { get; set; }

        
        public ActionResult Index()
        {
            return View();
        }

        /*Story*/

        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult StoryList(int? page, int? byuser) {
            ViewData["UrlPaging"] = Url.RouteUrl("PagginDefault", new { controller = "Admin", action = "StoryList", page = "__PAGENUM__" });
            IList<IStory> stories;
            ViewData["Title"] = "Preguntas";
            ViewData["ShowUserFilterLink"] = true;

            if (byuser != null) {
                IUser user = Userrepository.Get((long)byuser);
                stories = (from c in Storyrepository.GetAll()
                            where c.ByUser.Id == user.Id
                            orderby c.PostedAt descending
                            select c).ToList();
                ViewData["Title"] = "Preguntas [ Usuario: " + user.UserName + " ]";
                ViewData["ShowUserFilterLink"] = false;
            } else {
                stories = (from c in Storyrepository.GetAll()
                            orderby c.PostedAt descending
                            select c).ToList();
            }

            return View(stories.ToPagedList(page ?? 0, 20));
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult DisableStory(int id) {
            IStory story = Storyrepository.Get(id);
            story.IsLockedOut = true;
            Storyrepository.SaveOrUpdate(story);
            return RedirectToRoute("Admin", new { action = "StoryList" });
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EnableStory(int id) {
            IStory story = Storyrepository.Get(id);
            story.IsLockedOut = false;
            Storyrepository.SaveOrUpdate(story);
            return RedirectToRoute("Admin", new { action = "StoryList" });
        }


        /**/


        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult CommentList(int? page, int? byuser, int? bystory) {
            ViewData["UrlPaging"] = Url.RouteUrl("PagginDefault", new { controller = "Admin", action = "CommentList", page = "__PAGENUM__" });
            IList<IComment> comments;
            ViewData["Title"] = "Comentarios";
            ViewData["ShowUserFilterLink"] = true;
            ViewData["ShowStoryFilterLink"] = true;


            if (bystory != null) {
                IStory s = Storyrepository.Get((long) bystory);
                comments = (from c in Commentrepository.GetAll()
                            where c.ForStory.Id == s.Id 
                            orderby c.CommentedAt descending
                            select c).ToList();
                ViewData["Title"] = "Comentarios [ Pregunta: " + s.Title + " ]";
                ViewData["ShowStoryFilterLink"] = false;
            } else
            {
                if (byuser != null) {
                    IUser user = Userrepository.Get((long) byuser);
                    comments = (from c in Commentrepository.GetAll()
                                where c.ByUser.Id == user.Id
                                orderby c.CommentedAt descending
                                select c).ToList();
                    ViewData["Title"] = "Comentarios [ Usuario: " + user.UserName + " ]";
                    ViewData["ShowUserFilterLink"] = false;
                } else
                {
                    comments = (from c in Commentrepository.GetAll()
                                orderby c.CommentedAt descending
                                select c).ToList();
                }
            }

            return View(comments.ToPagedList(page ?? 0, 20));
        }

        [AcceptVerbs(HttpVerbs.Get)]        
        public ActionResult EditComment(int id) {
            IComment comment = Commentrepository.Get(id);
            return View(comment);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateAntiForgeryToken]
        public ActionResult EditComment(int id, FormCollection formData) {
            Markdown markDown = new Markdown();
            IComment comment = Commentrepository.Get(id);
            comment.TextBody = formData["comment.TextBody"];
            string htmltext = ExtraTools.Sanitize(markDown.Transform(comment.TextBody));
            comment.HtmlBody = htmltext;
            Commentrepository.SaveOrUpdate(comment);
            return RedirectToRoute("Admin", new { action = "CommentList" });
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult DeleteComment(int id) {
            IComment comment = Commentrepository.Get(id);
            Commentrepository.Delete(comment);
            return RedirectToRoute("Admin", new { action = "CommentList" });
        }


        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult SpamCommentList(int? page, int? byuser, int? bycomment) {
            ViewData["UrlPaging"] = Url.RouteUrl("PagginDefault", new { controller = "Admin", action = "CommentList", page = "__PAGENUM__" });
            IList<IMarkAsSpam<Comment>> spams;
            ViewData["Title"] = "Spams en Comentarios";
            ViewData["ShowUserFilterLink"] = true;
            ViewData["ShowCommentFilterLink"] = true;


            if (bycomment != null) {
                IComment comment = Commentrepository.Get((long) bycomment);
                spams = (from c in SpamCommentService.GetAll()
                            where c.SpamFor.Id == comment.Id
                            orderby c.MarkedAt descending
                            select c).ToList();
                ViewData["Title"] = "Spams [ Comentario ID: " + comment.Id + " ]";
                ViewData["ShowCommentFilterLink"] = false;
            } else {
                if (byuser != null) {
                    IUser user = Userrepository.Get((long)byuser);
                    spams = (from c in SpamCommentService.GetAll()
                             where c.SpamFor.ByUser.Id == user.Id
                             orderby c.MarkedAt descending
                             select c).ToList();
                    ViewData["Title"] = "Spams en comentarios por Usuario: " + user.UserName + " ]";
                    ViewData["ShowUserFilterLink"] = false;
                } else {
                    spams = (from c in SpamCommentService.GetAll()
                             orderby c.MarkedAt descending
                             select c).ToList();
                }
            }

            return View(spams.ToPagedList(page ?? 0, 20));
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult DeleteCommentSpam(int id) {
            IMarkAsSpam<Comment> spam = SpamCommentRepository.Get(id);
            SpamCommentRepository.Delete(spam);
            return RedirectToRoute("Admin", new { action = "SpamCommentList" });
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult AproveCommentSpam(int id) {
            IMarkAsSpam<Comment> spam = SpamCommentRepository.Get(id);
            spam.Approved = true;
            SpamCommentRepository.SaveOrUpdate(spam);
            return RedirectToRoute("Admin", new { action = "SpamCommentList" });
        }


        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult SpamStoryList(int? page, int? byuser, int? bystory) {
            ViewData["UrlPaging"] = Url.RouteUrl("PagginDefault", new { controller = "Admin", action = "CommentList", page = "__PAGENUM__" });
            IList<IMarkAsSpam<Story>> spams;
            ViewData["Title"] = "Spams en Preguntas";
            ViewData["ShowUserFilterLink"] = true;
            ViewData["ShowCommentFilterLink"] = true;


            if (bystory != null) {
                IStory story = Storyrepository.Get((long)bystory);
                spams = (from c in SpamStoryService.GetAll()
                         where c.SpamFor.Id == story.Id
                         orderby c.MarkedAt descending
                         select c).ToList();
                ViewData["Title"] = "Spams [ Pregunta ID: " + story.Id + " ]";
                ViewData["ShowStoryFilterLink"] = false;
            } else {
                if (byuser != null) {
                    IUser user = Userrepository.Get((long)byuser);
                    spams = (from c in SpamStoryService.GetAll()
                             where c.SpamFor.ByUser.Id == user.Id
                             orderby c.MarkedAt descending
                             select c).ToList();
                    ViewData["Title"] = "Spams en preguntas por Usuario: " + user.UserName + " ]";
                    ViewData["ShowUserFilterLink"] = false;
                } else {
                    spams = (from c in SpamStoryService.GetAll()
                             orderby c.MarkedAt descending
                             select c).ToList();
                }
            }

            return View(spams.ToPagedList(page ?? 0, 20));
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult DeleteStorySpam(int id) {
            IMarkAsSpam<Story> spam = SpamStoryRepository.Get(id);
            SpamStoryRepository.Delete(spam);
            return RedirectToRoute("Admin", new { action = "SpamStoryList" });
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult AproveStorySpam(int id) {
            IMarkAsSpam<Story> spam = SpamStoryRepository.Get(id);
            spam.Approved = true;
            SpamStoryRepository.SaveOrUpdate(spam);
            return RedirectToRoute("Admin", new { action = "SpamStoryList" });
        }


        //Users
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult UserList(int? page) {
            ViewData["UrlPaging"] = Url.RouteUrl("PagginDefault", new { controller = "Admin", action = "CommentList", page = "__PAGENUM__" });
            IList<IComment> comments;
            ViewData["Title"] = "Usuarios";

            var users = Userrepository.GetAll();

            return View(users.ToPagedList(page ?? 0, 20));
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult DisableUser(int id) {
            IUser user = Userrepository.Get(id);
            user.IsLockedOut = true;
            Userrepository.SaveOrUpdate(user);
            return RedirectToRoute("Admin", new { action = "UserList" });
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EnableUser(int id) {
            IUser user = Userrepository.Get(id);
            user.IsLockedOut = false;
            Userrepository.SaveOrUpdate(user);
            return RedirectToRoute("Admin", new { action = "UserList" });
        }

    }
}
